#include <jni.h>
#include "tactile_compass.h"
#include "bearing_module.h"
#include "common.h"

jclass waypoint_class;
jfieldID wp_lon, wp_lat, wp_alt;
static struct bearing_module_t *bm;
static int mode = 4;
static jobject hm_tc_callback;
static void tc_reached();

/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    onStart
 * Signature: ()V
 */
void Java_org_haptimap_hcimodules_TactileCompass_onStart(JNIEnv *env, jobject thiz) {
	hm_t *hm = GET_HM(thiz);
	waypoint_class = (*env)->FindClass(env, "org/haptimap/hcimodules/TactileCompass$Waypoint");
	wp_lon = (*env)->GetFieldID(env, waypoint_class, "lon", "F");
	wp_lat = (*env)->GetFieldID(env, waypoint_class, "lat", "F");
	wp_alt = (*env)->GetFieldID(env, waypoint_class, "alt", "F");

	bearing_start(hm, &bm);
	tactile_compass_start(bm, mode);
}
/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    onPause
 * Signature: ()V
 */
void Java_org_haptimap_hcimodules_TactileCompass_onPause(JNIEnv *env, jobject thiz) {
	tactile_compass_pause();
}
/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    onResume
 * Signature: ()V
 */
void Java_org_haptimap_hcimodules_TactileCompass_onResume(JNIEnv *env, jobject thiz) {
	tactile_compass_continue();
}
/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    onStop
 * Signature: ()V
 */
void Java_org_haptimap_hcimodules_TactileCompass_onStop(JNIEnv *env, jobject thiz){
	tactile_compass_stop();
}
/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    onDestroy
 * Signature: ()V
 */
void Java_org_haptimap_hcimodules_TactileCompass_onDestroy(JNIEnv *env, jobject thiz){
	tactile_compass_stop();
	bearing_stop();
}
/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    setMode
 * Signature: (Lorg/haptimap/hcimodules/TactileCompass/VectorCount;)I
 */
jint Java_org_haptimap_hcimodules_TactileCompass_setMode(JNIEnv *env, jobject thiz, jobject jmode){
	int m = GET_ORDINAL(jmode);
	if(m >= 0 && m <= 2) {
		switch(m) {
			case 0:
				mode = 4;
				break;
			case 1:
				mode = 6;
				break;
			case 2:
				mode = 8;
		}
	}
	else
		return HM_FAILURE;
	return HM_SUCCESS;
}
/*
 * Class:     org_haptimap_hcimodules_TactileCompass
 * Method:    setNextWaypoint
 * Signature: (Lorg/haptimap/hcimodules/TactileCompass/Waypoint;Lorg/haptimap/HaptiMap/HaptiMapCallbackType;)I
 */
jint Java_org_haptimap_hcimodules_TactileCompass_setNextWaypoint(JNIEnv *env, jobject thiz, jobject wp, jobject cb){
	jfloat lon, lat, alt;
	int uid;
	hm_t *hm = GET_HM(thiz);

	lon = (*env)->GetFloatField(env, wp, wp_lon);
	lat = (*env)->GetFloatField(env, wp, wp_lat);
	alt = (*env)->GetFloatField(env, wp, wp_alt);
	
	if((uid = hm_geo_point_add_wgs84_3d(hm, lon, lat, alt)) != -1)
		return HM_FAILURE;

	if(cb == NULL)
		tactile_compass_set_destination(NULL, uid);
	else {
		hm_tc_callback = cb;
		tactile_compass_set_destination(tc_reached, uid);
	}
	return HM_SUCCESS;
}

void tc_reached() {
	if(hm_tc_callback != NULL)
		hm_jni_callback_wrapper(hm_tc_callback);
}
